
import React, { useRef, useState, useEffect, useMemo, useCallback } from 'react';
import { Spin, Space, Card, Select, Slider, Button, Segmented, Typography, BackTop, Skeleton, message, Flex } from 'antd';
import styles from '../index.less';
import { throttle } from 'lodash';

// bing图片市场
const MKTS = [
    'zh-CN', 'en-US', 'en-GB', 'en-AU', 'en-CA', 'en-IN', 'ja-JP', 'fr-FR', 'fr-CA', 'de-DE', 'es-ES', 'it-IT', 'pt-BR', 'ko-KR'
];

const MAX_COUNT = 240; // 最大图片数量 (30次请求 × 8张/次)
const BATCH_SIZE = 20; // 每批加载的数量 (3次请求 × 8张/次)
const LOAD_THRESHOLD = 200; // 距离底部多少像素时开始加载

// 获取bing图片的批次
const fetchBingBatch = async (mkt, idx, n) => {
    const resp = await fetch(`/bing/HPImageArchive.aspx?format=js&uhd=1&idx=${idx}&n=${n}&mkt=${mkt}`);
    const json = await resp.json();
    const list = Array.isArray(json?.images) ? json.images : [];
    return list.map(i => ({
        src: `/bing${i.url}`,
        title: i.title,
        copyright: i.copyright,
        date: i.enddate,
        market: mkt,
    }));
};

// 按需获取bing图片 - 真正的按需加载
const fetchBingImagesOnDemand = async (mkts, startIndex, count, globalBatchOffset = 0) => {
    const map = new Map();
    const batchSize = 8; // 每次请求最多8张
    const neededBatches = Math.ceil(count / batchSize);
    
    console.log(`按需获取 ${count} 张图片，从索引 ${startIndex} 开始，预计需要 ${neededBatches} 次请求`);
    console.log(`可用市场列表: [${mkts.join(', ')}] (共${mkts.length}个市场)`);
    console.log(`全局批次偏移: ${globalBatchOffset}，确保市场轮换连续性`);
    
    // 创建市场轮换策略：确保每个请求都使用不同的市场+索引组合
    const createMarketStrategy = (baseIndex, batchIndex) => {
        // 使用全局批次偏移 + 当前批次索引，确保跨请求的市场轮换连续性
        const globalBatchIndex = globalBatchOffset + batchIndex;
        const marketIndex = globalBatchIndex % mkts.length;
        // 索引偏移基于全局批次索引除以市场数量
        const indexOffset = Math.floor(globalBatchIndex / mkts.length);
        return {
            market: mkts[marketIndex],
            index: baseIndex + indexOffset
        };
    };
    
    // 创建更精确的去重键：市场+URL+日期的组合
    const createDedupKey = (item, market) => {
        return `${market}_${item.src}_${item.date || ''}`;
    };
    
    for (let idx = 0; idx < neededBatches && map.size < count; idx++) {
        const need = Math.min(batchSize, count - map.size);
        const strategy = createMarketStrategy(startIndex, idx);
        
        console.log(`第 ${idx + 1}/${neededBatches} 次：市场 ${strategy.market}，索引 ${strategy.index}，获取 ${need} 张图片`);
        
        try {
            const batch = await fetchBingBatch(strategy.market, strategy.index, need);
            
            // 添加市场信息到每个图片项，便于调试
            const enrichedBatch = batch.map(item => ({
                ...item,
                requestMarket: strategy.market,
                requestIndex: strategy.index
            }));
            
            // 统计本次新增数量（在添加到map之前）
            let newItemsCount = 0;
            enrichedBatch.forEach(item => {
                const dedupKey = createDedupKey(item, strategy.market);
                if (!map.has(dedupKey)) { 
                    map.set(dedupKey, item);
                    newItemsCount++;
                } else {
                    console.log(`去重：跳过重复图片 ${item.title} (市场: ${strategy.market})`);
                }
            });
            
            console.log(`已获取 ${map.size} 张图片，目标 ${count} 张，本次新增 ${newItemsCount} 张`);
            
            // 如果已经获取足够的图片，提前退出
            if (map.size >= count) {
                break;
            }
        } catch (error) {
            console.error(`请求失败，市场 ${strategy.market}，索引 ${strategy.index}:`, error);
            // 继续尝试下一个请求
        }
    }
    
    const result = Array.from(map.values()).slice(0, count); // 确保不超过请求数量
    console.log(`按需获取到 ${result.length} 张图片`);
    
    // 输出图片来源统计
    const marketStats = {};
    result.forEach(item => {
        const market = item.requestMarket || 'unknown';
        marketStats[market] = (marketStats[market] || 0) + 1;
    });
    console.log('图片来源统计:', marketStats);
    
    return { result, batchCount: neededBatches };
};


const Lazyimgs = () => {
    const scrollContainerRef = useRef(null);
    const observerRef = useRef(null);
    const loadingLockRef = useRef(false); // 添加加载锁
    const globalBatchOffsetRef = useRef(0); // 全局批次偏移量，确保市场轮换连续性

    const [images, setImages] = useState([]);
    const [loading, setLoading] = useState(false);
    const [hasMore, setHasMore] = useState(true);
    const [currentIndex, setCurrentIndex] = useState(0); // 当前已请求的图片数量


    // 初始化数据 - 按需加载第一批
    useEffect(() => {
        let mounted = true;
        const run = async () => {
            setLoading(true);
              try {
                  const { result: items } = await fetchBingImagesOnDemand(MKTS, 0, BATCH_SIZE, globalBatchOffsetRef.current);
                  globalBatchOffsetRef.current += Math.ceil(BATCH_SIZE / 8);
                  if (mounted) {
                      setImages(items);
                    setCurrentIndex(items.length);
                    setHasMore(items.length >= BATCH_SIZE && currentIndex + items.length < MAX_COUNT);
                    const expectedRequests = Math.ceil(BATCH_SIZE / 8);
                    message.info(`初始加载 ${items.length} 张图片 (预计${expectedRequests}次请求)`);
                }
            } catch (error) {
                message.error('加载图片失败');
            } finally {
                if (mounted) {
                    setLoading(false);
                }
            }
        };
        run();
        return () => { mounted = false; };
    }, []);

    // 加载更多图片 - 按需请求
    const loadMore = useCallback(async () => {
        // 双重检查：loading状态 + 加载锁
        if (loading || !hasMore || loadingLockRef.current) {
            console.log('loadMore被阻止:', { loading, hasMore, loadingLock: loadingLockRef.current });
            return;
        }
        
        // 立即设置加载锁，防止重复触发
        loadingLockRef.current = true;
        console.log('loadMore开始执行，设置加载锁');
        
        try {
            // 再次检查状态（防止在设置锁期间状态发生变化）
            if (!hasMore) {
                console.log('检查发现hasMore为false，退出');
                return;
            }
            
            console.log('开始按需加载更多，当前索引:', currentIndex, '当前图片数:', images.length);
            
            // 检查是否达到最大数量
            if (currentIndex >= MAX_COUNT) {
                console.log('已达到最大图片数量，停止加载');
                setHasMore(false);
                message.info('已加载所有图片');
                return;
            }
            
            setLoading(true);
            
            // 计算本次需要加载的数量
            const remainingCount = Math.min(BATCH_SIZE, MAX_COUNT - currentIndex);
            console.log(`按需请求 ${remainingCount} 张图片，从索引 ${currentIndex} 开始`);
              
              const { result: newItems } = await fetchBingImagesOnDemand(MKTS, currentIndex, remainingCount, globalBatchOffsetRef.current);
              globalBatchOffsetRef.current += Math.ceil(remainingCount / 8);
              
              if (newItems.length > 0) {
                setImages(prev => [...prev, ...newItems]);
                const newIndex = currentIndex + newItems.length;
                setCurrentIndex(newIndex);
                
                // 检查是否还有更多图片
                const hasMoreImages = newIndex < MAX_COUNT;
                setHasMore(hasMoreImages);
                
                if (!hasMoreImages) {
                    message.info('已加载所有图片');
                } else {
                    message.info(`加载了 ${newItems.length} 张图片，当前显示 ${newIndex} 张`);
                }
            } else {
                setHasMore(false);
                message.info('没有更多图片了');
            }
        } catch (error) {
            console.error('loadMore执行出错:', error);
            message.error('加载更多图片失败');
        } finally {
            setLoading(false);
            // 释放加载锁
            loadingLockRef.current = false;
            console.log('loadMore执行完成，释放加载锁');
        }
    }, [loading, hasMore, currentIndex, images.length]);


    // 滚动事件处理
    const handleScroll = throttle(() => {
        if (!scrollContainerRef.current || loading || !hasMore || loadingLockRef.current) {
            return;
        }
        
        const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current;
        // 当滚动到距离底部 LOAD_THRESHOLD 像素时开始加载
        if (scrollTop + clientHeight >= scrollHeight - LOAD_THRESHOLD) {
            console.log('滚动触发加载更多，位置:', scrollTop + clientHeight, '>=', scrollHeight - LOAD_THRESHOLD);
            loadMore();
        }
    }, 200); // 200ms节流间隔

    // 添加滚动监听(只触发一次)
    useEffect(() => {
        const container = scrollContainerRef.current;
        if (!container) return;
    
        container.addEventListener('scroll', handleScroll, { passive: true });
        
        return () => {
            container.removeEventListener('scroll', handleScroll);
            
        };
    }, []);

    // IntersectionObserver设置 - 只在组件挂载时创建一次
    useEffect(() => {
        if (!scrollContainerRef.current) return;
        
        if (observerRef.current) {
            observerRef.current.disconnect();
        }
        
        observerRef.current = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    const img = entry.target;
                    const src = img.getAttribute('data-src');
                    if (src && !img.getAttribute('src')) {
                        img.setAttribute('src', src);
                    }
                    console.log('图片在可视区域内，配置src');
                    observerRef.current.unobserve(img);
                }
            });
        }, { 
            root: scrollContainerRef.current, 
            rootMargin: '300px' 
        });

        // 清理函数
        return () => {
            if (observerRef.current) {
                observerRef.current.disconnect();
            }
        };
    }, []); // 空依赖数组，只在挂载时执行一次

    // 监听图片变化，将新图片添加到观察器
    useEffect(() => {
        if (!observerRef.current) return;
        
        const images = document.querySelectorAll('[data-src]');
        images.forEach(img => {
            if (!img.getAttribute('src')) {
                observerRef.current.observe(img);
            }
        });
    }, [images]); // 当images数组变化时，重新观察新的图片


    // 骨架屏
    const SkeletonCard = () => (
        <>
            {
                [...Array(4)].map((_, index) => (
                    <Skeleton.Image key={index} style={{width:'100%',height: 300,marginBottom:20}} active={true} />
                ))
            }
        </>
    );

    // 底部加载状态
    const LoadMoreIndicator = () => {
        if (!hasMore && images.length > 0) {
            return (
                <div style={{ textAlign: 'center', padding: '20px', color: '#999' }}>
                    已加载全部图片 ({images.length} 张)
                </div>
            );
        }
        
        if (loading) {
            return (
                <div style={{ textAlign: 'center', padding: '20px' }}>
                    <Spin size="large" />
                    <div style={{ marginTop: '10px', color: '#666' }}>正在加载更多图片...</div>
                </div>
            );
        }
        
        return null;
    };
    
    return (
        <div className={styles.container} >
            <div className={styles.header}>
                <h2>懒加载图片演示</h2>
                <p>总数据量：{MAX_COUNT} &nbsp; 当前显示: {images.length} 张图片 {hasMore ? '(滚动加载更多)' : '(已全部加载)'}</p>
                <p>采用 <strong>IntersectionObserver</strong> 判断图片是否在可视区域</p>
            </div>
            <div className={styles.main} ref={scrollContainerRef} style={{ height: '600px', overflow: 'auto' }}>
                {
                    images.length === 0 && loading ? <SkeletonCard /> :
                    <>
                        {images.map((item, index) => (
                            <Card key={`${item.src}-${index}`} title="必应每日图片" style={{width:'100%',marginBottom:20}}>
                                <img 
                                    data-src={item.src} 
                                    alt={item.title} 
                                    style={{width:'100%',height: 600}} 
                                />
                                <div style={{ marginTop: '10px', fontSize: '12px', color: '#666' }}>
                                    {item.title} - {item.date}
                                </div>
                            </Card>
                        ))}
                        <LoadMoreIndicator />
                    </>
                }
            </div>
        </div>
    );
};

export default Lazyimgs;
